博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
selector
阅读量:218 次
发布时间:2019-02-28

本文共 6606 字,大约阅读时间需要 22 分钟。

selector根据不同的选定状态来定义不同的现实效果

view的状态:

android:drawable //放一个drawable资源,Android:background=drawable或者colorandroid:state_pressed //是否按下,如一个按钮触摸或者点击。android:state_focused //是否取得焦点,比如用户选择了一个文本框。android:state_hovered //光标是否悬停,通常与focused state相同,它是4.0的新特性android:state_selected //被选中,它与focus state并不完全一样,如一个list view 被选中的时候,//它里面的各个子组件可能通过方向键,被选中了。android:state_checkable //组件是否能被check。如:RadioButton是可以被check的。android:state_checked //被checked了,如:一个RadioButton可以被check了。android:state_enabled //能够接受触摸或者点击事件android:state_activated //被激活(这个麻烦举个例子,不是特明白)android:state_window_focused //应用程序是否在前台,当有通知栏被拉下来或者一个对话框弹出的时候应用程序就不在前台了

selected和focused的区别有如下几点:

1、selected不同于focus状态,通常在AdapterView类群下例如ListView或者GridView会使某个View处于

selected状态,并且获得该状态的View处于高亮状态。

2、一个窗口只能有一个视图获得焦点(focus),而一个窗口可以有多个视图处于”selected”状态中。

总结:

focused状态一般是由按键操作引起的;
pressed状态是由触摸消息引起的; selected则完全是由应用程序主动调用setSelected()进行控制。

有的需要加android:focusable和android:clickable为true才能获取焦点。

当一个不可点击的view(如:imageview/textview)设置android:clickable=”true”才可以像button一样点击。然后背景颜色android:background=”@drawable/选择颜色的xml文件名”可设置点击、非点击两种状态颜色,这个背景状态改变,只有在clickable=true才有效。

常用checkbox设置:

常用ImageButton设置:

常用Button设置:

常用TextView设置:

其实,前面说的xml文件,最终会被Android框架解析成StateListDrawable类对象。所以除了使用XML文件定义selector,然后设置drawable或者color外还可以使用StateListDrawable类动态定义selector。

1、从XML中解析出StateListDrawable的过程。

从XML中解析出StateListDrawable的过程。

2、View的DrawableState的设置过程

View的DrawableState的设置过程

3、View的DrawableState变化过程。

View的DrawableState变化过程

StateListDrawable类:

public class StateListDrawable extends DrawableContainer {
}public class DrawableContainer extends Drawable implements Callback {
}

类功能说明:该类定义了不同状态值下与之对应的图片资源,即我们可以利用该类保存多种状态值,多种图片资源。

常用方法为:

public void addState (int[] stateSet, Drawable drawable)

功能: 给特定的状态集合设置drawable图片资源

例子如下:

//初始化一个空对象        StateListDrawable stalistDrawable = new StateListDrawable();        //获取对应的属性值 Android框架自带的属性 attr        int pressed = android.R.attr.state_pressed;        int window_focused = android.R.attr.state_window_focused;        int focused = android.R.attr.state_focused;        int selected = android.R.attr.state_selected;        stalistDrawable.addState(new int[]{pressed, window_focused}, getResources()        .getDrawable(R.drawable.guide_1));        stalistDrawable.addState(new int[]{pressed, -focused}, getResources()        .getDrawable(R.drawable.guide_2));        stalistDrawable.addState(new int[]{selected}, getResources()        .getDrawable(R.drawable.guide_3));        stalistDrawable.addState(new int[]{focused}, getResources()        .getDrawable(R.drawable.guide_4));        //没有任何状态时显示的图片,我们给它设置我空集合        stalistDrawable.addState(new int[]{}, getResources()        .getDrawable(R.mipmap.ic_launcher));         Drawable mBackground = statelistDrawable;        // 必须设置回调,当改变状态时,会回掉该View进行invalidate()刷新操作.        mBackground.setCallback(this);        // 取消默认的背景图片,因为我们设置了自己的背景图片了,否则可能造成背景图片重叠。        this.setBackgroundDrawable(null);

上面的“-”负号表示对应的属性值为false

当我们为某个View使用其作为背景色时,会根据状态进行背景图的转换。

public boolean isStateful ()

功能: 表明该状态改变了,对应的drawable图片是否会改变。

注:在StateListDrawable类中,该方法返回为true,显然状态改变后,我们的图片会跟着改变。

当View任何状态值发生改变时,都会调用refreshDrawableList()方法去更新对应的背景Drawable对象。

//主要功能是根据当前的状态值去更换对应的背景Drawable对象      public void refreshDrawableState() {          mPrivateFlags |= DRAWABLE_STATE_DIRTY;          //所有功能在这个函数里去完成          drawableStateChanged();          ...      }        // 获得当前的状态属性--- 整型集合 ; 调用Drawable类的setState方法去获取资源。      protected void drawableStateChanged() {          //该视图对应的Drawable对象,通常对应于StateListDrawable类对象          Drawable d = mBGDrawable;             if (d != null && d.isStateful()) {  //通常都是成立的              //getDrawableState()方法主要功能:会根据当前View的状态属性值,将其转换为一个整型集合              //setState()方法主要功能:根据当前的获取到的状态,更新对应状态下的Drawable对象。              d.setState(getDrawableState());          }      }        public final int[] getDrawableState() {          if ((mDrawableState != null) && ((mPrivateFlags & DRAWABLE_STATE_DIRTY) == 0)) {              return mDrawableState;          } else {              //根据当前View的状态属性值,将其转换为一个整型集合,并返回              mDrawableState = onCreateDrawableState(0);              mPrivateFlags &= ~DRAWABLE_STATE_DIRTY;              return mDrawableState;          }      }

setState()函数原型 :

//如果状态态值发生了改变,就回调onStateChange()方法。  public boolean setState(final int[] stateSet) {      if (!Arrays.equals(mStateSet, stateSet)) {          mStateSet = stateSet;          return onStateChange(stateSet);      }      return false;  }

该函数的主要功能: 判断状态值是否发生了变化,如果发生了变化,就调用onStateChange()方法进一步处理。

onStateChange()函数原型:

//状态值发生了改变,我们需要找出第一个吻合的当前状态的Drawable对象  protected boolean onStateChange(int[] stateSet) {      //要找出第一个吻合的当前状态的Drawable对象所在的索引位置, 具体匹配算法请自己深入源码看看      int idx = mStateListState.indexOfStateSet(stateSet);      ...      //获取对应索引位置的Drawable对象      if (selectDrawable(idx)) {          return true;      }      ...  }

该函数的主要功能: 根据新的状态值,从StateListDrawable实例对象中,找到第一个完全吻合该新状态值的索引下标处 ;

继而,调用selectDrawable()方法去获取索引下标的当前Drawable对象。
具体查找算法在 mStateListState.indexOfStateSet(stateSet) 里实现了。基本思路是:查找第一个能完全吻合该新状态值
的索引下标,如果找到了,则立即返回。

selectDrawable()函数原型:

public boolean selectDrawable(int idx)  {      if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {          //获取对应索引位置的Drawable对象          Drawable d = mDrawableContainerState.mDrawables[idx];          ...          mCurrDrawable = d; //mCurrDrawable即使当前Drawable对象          mCurIndex = idx;          ...      } else {         ...      }      //请求该View刷新自己,这个方法我们稍后讲解。      invalidateSelf();      return true;  }

参考:

推荐:

android中设置TextView的颜色有方法setTextColor,这个方法被重载了,可以传入两种参数。

public void setTextColor(int color) {      mTextColor = ColorStateList.valueOf(color);      updateTextColors();  }  public void setTextColor(ColorStateList colors) {      if (colors == null) {          throw new NullPointerException();      }      mTextColor = colors;      updateTextColors();  }

设置如下:

tv.setTextColor(Color.parseColor("#FFFFFF"));  //代码中通过argb值的方式  tv.setTextColor(Color.rgb(255, 255, 255)); //通过资源引用  tv.setTextColor(getResources().getColor(R.color.my_color));//通过资源文件写在String.xml中  Resources resource = (Resources) getBaseContext().getResources();  ColorStateList csl = (ColorStateList) resource.getColorStateList(R.color.my_color); if (csl != null) {    tv.setTextColor(csl);  }  //通过xml文件,如/res/color/text_color.xmlXmlPullParser xrp = getResources().getXml(R.color.text_color);  try {        ColorStateList csl = ColorStateList.createFromXml(getResources(), xrp);        tv.setTextColor(csl);    } catch (Exception e) {  }

转载地址:http://yyss.baihongyu.com/

你可能感兴趣的文章